﻿using System.Collections;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;


namespace Marmat.Forms
{
    public partial class TreeView
    {

        /// <summary>
        /// 绘制更新区域
        /// </summary>
        /// <value></value>
        /// <returns></returns>
        /// <remarks></remarks>
        protected internal bool DrawUpdate { get; set; } = true;


        /// <summary>
        /// 禁用任何树视图重绘。
        /// </summary>
        /// <remarks></remarks>
        public void BeginUpdate()
        {
            this.DrawUpdate = false;
        }

        /// <summary>
        /// 启用树视图的重绘。
        /// </summary>
        /// <remarks></remarks>
        public void EndUpdate()
        {
            this.DrawUpdate = true;
        }

        /// <summary>
        /// 折叠所有树节点。
        /// </summary>
        /// <remarks></remarks>
        public void CollapseAll()
        {
            var Items = this.GetAllTreeNode();
            foreach (TreeNode Item in Items)
                Item.m_IsExpanded = false;
            this.Invalidate();
        }

        /// <summary>
        /// 展开所有树节点。
        /// </summary>
        /// <remarks></remarks>
        public void ExpandAll()
        {
            var Items = this.GetAllTreeNode();
            foreach (TreeNode Item in Items)
                Item.m_IsExpanded = true;
            this.Invalidate();
        }

        /// <summary>
        /// 对 System.Windows.Forms.TreeView 控件中的项进行排序。
        /// </summary>
        /// <remarks></remarks>
        public void Sort()
        {
            this.Sort_Method(this.Nodes);
            this.Invalidate();
        }

        private void Sort_Method(TreeNodeCollection nodes)
        {

            if (nodes.Count > 0)
            {
                using var dt = new DataTable();
                dt.Columns.Add("Object", typeof(object));
                dt.Columns.Add("Name", typeof(object));
                foreach (TreeNode nd in nodes)
                {
                    var dr = dt.NewRow();
                    dr["Name"] = nd.Text;
                    dr["Object"] = nd;
                    dt.Rows.Add(dr);
                    this.Sort_Method(nd.Nodes);
                }

                foreach (DataRow dr in dt.Select("", "Name DESC"))
                {
                    nodes.Remove((TreeNode)dr["Object"]);
                    nodes.Insert(0, (TreeNode)dr["Object"]);
                }
            }
        }


        /// <summary>
        /// 检索位于指定点（以坐标表示）的树节点。
        /// </summary>
        /// <param name="x">要从其计算和检索节点的 System.Drawing.Point.X 位置。</param>
        /// <param name="y">要从其计算和检索节点的 System.Drawing.Point.Y 位置。</param>
        /// <returns>位于以树视图（客户端）坐标表示的指定位置的 TreeNode，或在该位置没有节点时为 null。</returns>
        /// <remarks></remarks>
        public TreeNode GetNodeAt(int x, int y)
        {
            return this.GetNodeAt(new Point(x, y));
        }
        /// <summary>
        /// 检索位于指定点的树节点。
        /// </summary>
        /// <param name="pt">要从其计算和检索节点的 System.Drawing.Point。</param>
        /// <returns>位于以树视图（客户端）坐标表示的指定点的 TreeNode，或在该位置没有节点时为 null。</returns>
        /// <remarks></remarks>
        public TreeNode GetNodeAt(Point pt)
        {
            var Items = this.GetAllTreeNode();
            foreach (TreeNode Item in Items)
            {
                if (Item.Parent is null || Item.Parent.IsExpanded == true)
                {
                    if (Item.Bounds != default && Item.Bounds.Contains(pt))
                    {
                        return Item;
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// 检索分配给树视图控件的树节点数（可以选择性地包括所有子树中的树节点）。
        /// </summary>
        /// <param name="includeSubTrees">includeSubTrees: 如果计入子树包含的 System.Windows.Forms.TreeNode 项，则为 true；否则为 false。</param>
        /// <returns>分配给树视图控件的树节点数（可以选择性地包括所有子树中的树节点）。</returns>
        /// <remarks></remarks>
        public int GetNodeCount(bool includeSubTrees)
        {
            if (includeSubTrees)
            {
                return this.GetAllTreeNode().Count;
            }
            else
            {
                return this.Nodes.Count;
            }
        }

        /// <summary>
        /// 在给定 x 和 y 坐标的情况下，提供节点信息。
        /// </summary>
        /// <param name="x">在其中检索节点信息的 x 坐标。</param>
        /// <param name="y">在其中检索节点信息的 y 坐标。</param>
        /// <returns>System.Windows.Forms.TreeViewHitTestInfo。</returns>
        /// <remarks></remarks>
        public TreeViewHitTestInfo HitTest(int x, int y)
        {
            return this.HitTest(new Point(x, y));
        }

        /// <summary>
        /// 在给定一个点的情况下，提供节点信息。
        /// </summary>
        /// <param name="pt">在其中检索节点信息的 System.Drawing.Point。</param>
        /// <returns>System.Windows.Forms.TreeViewHitTestInfo。</returns>
        /// <remarks></remarks>
        public TreeViewHitTestInfo HitTest(Point pt)
        {
            TreeViewHitTestInfo Result = null;
            var nd = this.GetNodeAt(pt);
            if (nd is object)
            {
                Result = new TreeViewHitTestInfo(nd, TreeViewHitTestLocations.None);
            }

            return Result;
        }

        /// <summary>
        /// 确定指定的键是常规输入键还是需要预处理的特殊键。
        /// </summary>
        /// <param name="keyData">一个键值。</param>
        /// <returns>如果指定的键是常规输入键，则为 true；否则为 false。</returns>
        /// <remarks></remarks>
        protected override bool IsInputKey(Keys keyData)
        {
            return default;
        }
    }
}